描述
给一个字符串,返回字典序最大的substring.
思路
常规解法是后缀数组(倍增法), 然后拿到sa
数组最后一个元素(最大substring起始点).
最优解是用类似字符串最小表示法的O(n)
解, 维护两个指针i
,j
表示当前正在比较的两个substring的起始点, 另一个k
表示substring长度. 每次比较发生在s[i+k]
和s[j+k]
之间. match就k+1否则更新i,j.
当k
前进一段距离, s[i+k]
和s[j+k]
失配时有一个特征:
- 如果当前
s[i+k]
更大, 需要更新j
. (我们试图用j
找一个更大的substring起始点, 然后替换i
). 这个时候在[j:j+k]
闭区间的所有字符都是不大于s[i]
的.否则我们不会等到现在才更新j,之前只要遇到比s[i]
大的就已经更新了.
这个时候可以直接j = j + k + 1
- 如果当前
s[j+k]
更大, 那么找到了一个更大的substring, 需要用j
的值去更新i
, 然后j
移动到i
的下一个位置.代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19class Solution(object):
def lastSubstring(self, s):
"""
:type s: str
:rtype: str
"""
i, j, k = 0, 1, 0
n = len(s)
while j + k < n:
if s[i+k] == s[j+k]:
k += 1
continue
elif s[i+k] > s[j+k]:
j = j + k + 1
else:
i = j
j = i + 1
k = 0
return s[i:]
倍增法(模板)
这个题用python写倍增仍然会TLE, 可能是常数项比较大, 不是单纯的O(nlogn)
了…
1 | class Solution(object): |